package versi.vitro.oaiserviceprovider.service.transformer.impl;

import javax.xml.transform.Result;
import javax.xml.transform.Source;

import org.jmock.Expectations;
import org.jmock.Mockery;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import versi.vitro.oaiserviceprovider.service.transformer.api.StreamFactory;
import versi.vitro.oaiserviceprovider.service.transformer.api.TransformerService;
import versi.vitro.oaiserviceprovider.service.transformer.impl.TransformerServiceImpl;
import versi.vitro.oaiserviceprovider.xml.XmlTransformer;
import versi.vitro.oaiserviceprovider.xml.XmlTransformerFactory;

public class TransformationServiceImplTest {

    private Mockery context;

    @BeforeMethod
    public void setUp() {
	context = new Mockery();
    }

    @Test
    public void testApplyXSLT() {

	final String sourceXmlStr = "<root></root>";
	final String sourceXsltStr = "<style></style>";
	final byte[] sourceXmlBytes =  sourceXmlStr.getBytes();
	final byte[] sourceXsltBytes = sourceXsltStr.getBytes();
		
	final Source xmlInput = context.mock(Source.class, "xmlInput");
	context.checking(new Expectations() {
	    {
	    }
	});

	final Source xsltInput = context.mock(Source.class, "xsltInput");
	context.checking(new Expectations() {
	    {
	    }
	});

	final Result xmlOutput = context.mock(Result.class);
	context.checking(new Expectations() {
	    {
	    }
	});

	final StreamFactory connectionFactory = context.mock(StreamFactory.class);
	context.checking(new Expectations() {
	    {
		exactly(1).of(connectionFactory).createXmlInputSource(); will(returnValue(xmlInput));
		exactly(1).of(connectionFactory).createXsltInputSource(); will(returnValue(xsltInput));
		exactly(1).of(connectionFactory).createXmlOutputResult(); will(returnValue(xmlOutput));
		exactly(1).of(connectionFactory).close(); ;
		exactly(1).of(connectionFactory).xmlResult(); ;
	    }
	});

	final XmlTransformer transformer = context.mock(XmlTransformer.class);
	context.checking(new Expectations() {
	    {
		exactly(1).of(transformer).transform(xmlInput, xmlOutput);
	    }
	});

	final XmlTransformerFactory transformerFactory = context.mock(XmlTransformerFactory.class);
	context.checking(new Expectations() {
	    {
		exactly(1).of(transformerFactory).create(xsltInput); will(returnValue(transformer));
	    }
	});

	TransformerService transformationService = new TransformerServiceImpl(transformerFactory)
	{
	    protected StreamFactory createConnectionFactory(byte[] source, byte[] xslt) {
		assert sourceXmlStr.equals(new String(source));
		assert sourceXsltStr.equals(new String(xslt));
		return connectionFactory;
	    }
	};
	
	transformationService.applyXSLT(sourceXmlBytes, sourceXsltBytes);

	context.assertIsSatisfied();
    }
}
